{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 二元运算"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": [
    "import numpy as np"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 四则运算 "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运算|函数\n",
    "--- | --- \n",
    "`a + b` | `add(a,b)`\n",
    "`a - b` | `subtract(a,b)`\n",
    "`a * b` | `multiply(a,b)`\n",
    "`a / b` | `divide(a,b)`\n",
    "`a ** b` | `power(a,b)`\n",
    "`a % b` | `remainder(a,b)`\n",
    "\n",
    "以乘法为例，数组与标量相乘，相当于数组的每个元素乘以这个标量："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 6])"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1,2])\n",
    "a * 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "数组逐元素相乘："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 8])"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1,2])\n",
    "b = np.array([3,4])\n",
    "a * b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "使用函数："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 8])"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.multiply(a, b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "事实上，函数还可以接受第三个参数，表示将结果存入第三个参数中："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 8])"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "np.multiply(a, b, a)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([3, 8])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 比较和逻辑运算"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "运算|函数<\n",
    "--- | --- \n",
    "`==` | `equal`\n",
    "`!=` | `not_equal`\n",
    "`>` | `greater`\n",
    "`>=` | `greater_equal`\n",
    "`<` | `less`\n",
    "`<=` | `less_equal`\n",
    "| `logical_and`\n",
    "| `logical_or`\n",
    "| `logical_xor`\n",
    "| `logical_not`\n",
    "`&` | `bitwise_and`\n",
    " | `bitwise_or`\n",
    "`^` | `bitwise_xor`\n",
    "`~` | `invert`\n",
    "`>>` | `right_shift`\n",
    "`<<` | `left_shift`\n",
    "\n",
    "等于操作也是逐元素比较的："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([[ True,  True, False,  True],\n",
       "       [False,  True,  True,  True]], dtype=bool)"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([[1,2,3,4],\n",
    "              [2,3,4,5]])\n",
    "b = np.array([[1,2,5,4],\n",
    "              [1,3,4,5]])\n",
    "a == b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "这意味着，如果我们在条件中要判断两个数组是否一样时，不能直接使用\n",
    "\n",
    "    if a == b:\n",
    "\n",
    "而要使用：\n",
    "\n",
    "    if all(a==b):\n",
    "\n",
    "对于浮点数，由于存在精度问题，使用函数 `allclose` 会更好：\n",
    "\n",
    "    if allclose(a,b):\n",
    "\n",
    "`logical_and` 也是逐元素的 `and` 操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False,  True, False], dtype=bool)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([0,1,2])\n",
    "b = np.array([0,10,0])\n",
    "\n",
    "np.logical_and(a, b)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "`0` 被认为是 `False`，非零则是 `True`。"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "比特操作："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 17,  34,  68, 136])"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1,2,4,8])\n",
    "b = np.array([16,32,64,128])\n",
    "\n",
    "a | b"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "取反："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([254, 253, 252, 251], dtype=uint8)"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1,2,3,4], np.uint8)\n",
    "~a"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "左移："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 8, 16, 24, 32], dtype=uint8)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a << 3"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "要注意的是 `&` 的运算优先于比较运算如 `>` 等，所以必要时候需要加上括号："
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([False, False,  True, False], dtype=bool)"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "a = np.array([1,2,4,8])\n",
    "b = np.array([16,32,64,128])\n",
    "\n",
    "(a > 3) & (b < 100)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 2",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.10"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
